/*
 Copyright (C) 2010 Kristian Duske

 This file is part of TrenchBroom.

 TrenchBroom is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 TrenchBroom is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with TrenchBroom.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "SpinControl.h"

#include <QGuiApplication>

#include "ui/QtUtils.h"

#include "kd/contracts.h"
#include "kd/string_utils.h"

namespace tb::ui
{
SpinControl::SpinControl(QWidget* parent)
  : QDoubleSpinBox{parent}
{
  setKeyboardTracking(false);
  updateTooltip();
}

void SpinControl::stepBy(int steps)
{
  if (QGuiApplication::keyboardModifiers() & Qt::ShiftModifier)
  {
    setSingleStep(m_shiftIncrement);
  }
  else if (QGuiApplication::keyboardModifiers() & Qt::ControlModifier)
  {
    setSingleStep(m_ctrlIncrement);
    // QAbstractSpinBox steps by +/-10 if control is held (on most platforms; see #3373)
    steps = (steps > 0) ? 1 : -1;
  }
  else
  {
    setSingleStep(m_regularIncrement);
  }

  QDoubleSpinBox::stepBy(steps);
}

QString SpinControl::textFromValue(const double val) const
{
  auto str = QDoubleSpinBox::textFromValue(val);

  if (m_minDigits < m_maxDigits)
  {
    const auto zero = locale().zeroDigit();
    while (str.length() > m_minDigits && str[str.length() - 1] == zero)
    {
      str.chop(1);
    }
    const auto dec = locale().decimalPoint();
    if (!str.isEmpty() && str[str.length() - 1] == dec)
    {
      contract_assert(m_minDigits == 0);

      str.chop(1);
    }
  }

  return str;
}

void SpinControl::setIncrements(
  const double regularIncrement, const double shiftIncrement, const double ctrlIncrement)
{
  m_regularIncrement = regularIncrement;
  m_shiftIncrement = shiftIncrement;
  m_ctrlIncrement = ctrlIncrement;
  updateTooltip();
}

void SpinControl::setDigits(const int /* minDigits */, const int maxDigits)
{
  setDecimals(maxDigits);
}

void SpinControl::updateTooltip()
{
  setToolTip(tr("Increment: %1 (%2: %3, %4: %5)")
               .arg(QString::fromStdString(kdl::str_to_string(m_regularIncrement)))
               .arg(nativeModifierLabel(Qt::SHIFT))
               .arg(QString::fromStdString(kdl::str_to_string(m_shiftIncrement)))
               .arg(nativeModifierLabel(Qt::CTRL))
               .arg(QString::fromStdString(kdl::str_to_string(m_ctrlIncrement))));
}

} // namespace tb::ui
